/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.meraklisina.latexeditor.mdi.TextEditor;

import java.awt.BorderLayout ;
import java.awt.Color ;
import java.awt.Component;
import java.awt.Dimension ;
import java.awt.FlowLayout ;
import java.awt.Graphics ;
import java.awt.Insets;
import java.awt.Point ;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Observable ;
import java.util.Observer ;
import java.util.regex.Pattern ;

import javax.swing.JOptionPane;
import javax.swing.JPanel ;
import javax.swing.JTabbedPane ;
import javax.swing.JScrollPane ;
import javax.swing.text.BadLocationException ;
import javax.swing.text.Document ;
import javax.swing.text.Element ;

import com.meraklisina.latexeditor.mdi.Pane.SweTextPane;



public class NumberedPanel extends JPanel
{
    // for this simple experiment, we keep the pane + scrollpane as members.
    protected SweTextPane editor ;

    protected JScrollPane scrollPane ;
    
    private void setHighlightPatterns(SweTextPane Editor)
    {
    	Color ltxGreen = new Color(0, 120, 0);
    	Color ltxBlue = new Color(0, 0, 160);
    	Color ltxRed = new Color(160, 0, 0);
    	Color ltxDarkRed = new Color(80, 10, 10);
    	
    	String syntaxWords[] = new TextEditors().syntaxWords;
    	
    	Editor.putPattern( Pattern.compile( "(\\\\[a-zA-Z_0-9IıĞğÜüŞşİÇçÖö]*)" ), ltxDarkRed ) ;
    	
    	//Editor.putPattern( Pattern.compile( "(\\{[a-zA-Z_0-9 IıĞğÜüŞşİÇçÖö\\\\]*\\})" ), ltxBlue ) ;
    	Editor.putPattern( Pattern.compile( "(\\{[a-zA-Z_0-9IıĞğÜüŞşİÇçÖö\\-\\\\ ]*\\})" ), ltxBlue ) ;
    	
    	for(int i = 0; i < syntaxWords.length; i++)
    		Editor.putPattern( Pattern.compile( "(\\" + syntaxWords[i] + " " + ")" ), ltxRed ) ;
    	
    	
    	//Editor.putPattern( Pattern.compile( "(\\$[a-zA-Z_0-9 IıĞğÜüŞşİÇçÖö\\\\]*\\$)" ), ltxGreen ) ;	
    	Editor.putPattern( Pattern.compile( "(\\$.*\\$)" ), ltxGreen ) ;
    }

    /**
     * index starts from 0
     * Ex: Below text is in pane <br>
     * a<br>
     * bb<br>
     * ccc<br>
     * <br>
     * getLineStartOffset( 0 ) = 0<br>
     * getLineStartOffset( 1 ) = 2<br>
     * getLineStartOffset( 2 ) = 5<br>
     * @param index
     * @return the beginning of line
     */
    public int getLineStartOffset( int index )
    {
        Element section = this.editor.getDocument( ).getDefaultRootElement( ) ;
        Element e = section.getElement( index ) ;
        int rangeStart = e.getStartOffset( ) ;
        return rangeStart ;
    }

    /**
     * index starts from 0
     * Ex: Below text is in pane <br>
     * a<br>
     * bb<br>
     * ccc<br>
     * <br>
     * getLineEndOffset( 0 ) = 2<br>
     * getLineEndOffset( 1 ) = 5<br>
     * getLineEndOffset( 2 ) = 9<br>
     * @param index
     * @return the end of line
     */
    public int getLineEndOffset( int index )
    {
        Element section = this.editor.getDocument( ).getDefaultRootElement( ) ;
        Element e = section.getElement( index ) ;
        int rangeEnd = e.getEndOffset( ) ;
        return rangeEnd ;
    }

    /**
     * index starts from 0
     * Ex: Below text is in pane <br>
     * a<br>
     * bb<br>
     * ccc<br>
     * <br>
     * getLineText( 0 ) = a\n<br>
     * getLineText( 1 ) = bb\n<br>
     * getLineText( 2 ) = ccc\n<br>
     * @param index
     * @return the text at the line
     */
    public String getLineText( int index )
    {
        Element section = this.editor.getDocument( ).getDefaultRootElement( ) ;
        Element e = section.getElement( index ) ;
        int rangeStart = e.getStartOffset( ) ;
        int rangeEnd = e.getEndOffset( ) ;
        try
        {
            String lineText = this.editor.getText( rangeStart, rangeEnd - rangeStart ) ;
            return lineText ;
        }
        catch( BadLocationException ex )
        {
            ex.printStackTrace( ) ;
        }
        return null ;
    }

    public SweTextPane getEditor( )
    {
        return this.editor ;
    }

    public void setEditor( SweTextPane editor )
    {
        this.editor = editor ;
    }

    public NumberedPanel(final JTabbedPane TabEditors, SweTextPane Editor, JScrollPane ScrollPane, String Name, String NameEditor )
    {
        super( ) ;
        this.setBackground( Color.white ) ;

        this.setName( Name + "-NumberedPane" ) ;

        /*this.setMinimumSize( new Dimension( 30, 30 ) ) ;*/
        //***this.setPreferredSize( new Dimension( 340, 300 ) ) ;
        //this.setMinimumSize( new Dimension( 340, 300 ) ) ;
        Editor = new SweTextPane( ) // we need to override paint so that the linenumbers stay in sync
        {
            @Override
            public void paint( Graphics g )
            {
                super.paint( g ) ;
                NumberedPanel.this.repaint( ) ;
            }
        } ;

        KeyListener Listener = new KeyListener( )
        {
            public void keyTyped( KeyEvent evt )
            {
                SetIsTextChange( TabEditors, true ) ;
            }

            public void keyPressed( KeyEvent e )
            {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            public void keyReleased( KeyEvent e )
            {
                //throw new UnsupportedOperationException("Not supported yet.");
            }
        } ;
        Editor.addKeyListener( Listener ) ;

        Editor.setName( NameEditor ) ;

        this.setLayout( new BorderLayout( ) ) ;

        JPanel dumyPanel = new JPanel( ) ;
        dumyPanel.setMinimumSize( new Dimension(140, 1000 ) );
        dumyPanel.setPreferredSize( new Dimension( 30, 300 ) ) ;
        dumyPanel.setBackground( Color.WHITE );

        //this.setBackground( Color.BLUE );
        ///this.editor.setSize( 300, 400 );
        //this.editor.setBackground( Color.BLUE );
        //this.scrollPane = new JScrollPane( this.editor );//, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS ) ;
        ScrollPane = new JScrollPane( this.editor ) ;//, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS ) ;
        ScrollPane.setName( Name ) ;
        
        setHighlightPatterns(Editor);
        
        Editor.putPattern( Pattern.compile( "(%.*$)" ), Color.GRAY ) ;

        //this.setLayout( new FlowLayout() ) ;
        ScrollPane.setLocation( 20, -10 ) ;
        //*this.scrollPane.setSize( 300, 300 ) ;
        //ScrollPane.setSize( TabEditors.getWidth()-18, TabEditors.getHeight()-10 );
        //ScrollPane.setLayout( new FlowLayout() );

        //this.editor.setLocation( 30, 0 ) ;
        //this.editor.setSize( 330, 300 ) ;
        //this.editor.setMargin( new Insets(30,30,30,30) );

        Editor.getName( ) ;
        //this.add( this.editor ) ;
        //this.add( Editor ) ;

        //this.scrollPane.setViewportView(this.editor);
        Editor.setMargin( new Insets( 0, 10, 20, 5 ) ) ;
        ScrollPane.setViewportView( Editor ) ;
        //this.add( this.scrollPane ) ;
        //this.add( ScrollPane ) ;

        this.add( dumyPanel ,BorderLayout.WEST ) ;
        this.add( ScrollPane ,BorderLayout.CENTER ) ;
        

        //this.setSize( new Dimension( 340, 300 ) ) ;

        this.editor = Editor ;
        this.scrollPane = ScrollPane ;
        //this.scrollPane.setName(Name);
        Editor.getName( ) ;
        this.doLayout( ) ;

    }

    private void SetIsTextChange(JTabbedPane TabEditors, boolean IsChanged)
    {
        int Index = TabEditors.getSelectedIndex();

        if(IsChanged)
        {
            if(!TabEditors.getTitleAt(Index).contains("*"))
            {
                Component compTab = TabEditors.getTabComponentAt(TabEditors.getSelectedIndex());
                //JOptionPane.showMessageDialog(null, String.valueOf(compTab.getWidth()));
                compTab.setSize(compTab.getWidth() + 1, compTab.getHeight()); //Increases the 
                TabEditors.setTitleAt(Index, TabEditors.getTitleAt(Index) + " *");
            }
        }
        else
            TabEditors.setTitleAt(Index, TabEditors.getTitleAt(Index).replace(" *", ""));

        TextEditors tt = new TextEditors();
        tt.getEditors().get(Index).setIsTextChanged(IsChanged);
        //Editors.get(Index).setIsTextChanged(IsChanged);
    }

    @Override
    public void paint( Graphics g )
    {
        //g.translate( 20, 0 );
        super.paint( g ) ;
        //g.translate( -20, 0 );

        // We need to properly convert the points to match the viewport
        // Read docs for viewport
        int start = this.editor.viewToModel( this.scrollPane.getViewport( ).getViewPosition( ) ) ; //starting pos in document
        int end = this.editor.viewToModel( new Point( this.scrollPane.getViewport( ).getViewPosition( ).x + this.editor.getWidth( ), this.scrollPane.getViewport( ).getViewPosition( ).y + this.editor.getHeight( ) ) ) ;
        // end pos in doc

        // translate offsets to lines
        Document doc = this.editor.getDocument( ) ;
        int startline = doc.getDefaultRootElement( ).getElementIndex( start ) + 1 ;
        int endline = doc.getDefaultRootElement( ).getElementIndex( end ) + 1 ;

        int fontHeight = g.getFontMetrics( this.editor.getFont( ) ).getHeight( ) ;
        int fontDesc = g.getFontMetrics( this.editor.getFont( ) ).getDescent( ) ;
        int starting_y = -1 ;

        try
        {
            starting_y = this.editor.modelToView( start ).y - this.scrollPane.getViewport( ).getViewPosition( ).y + fontHeight - fontDesc ;
        }
        catch( BadLocationException e1 )
        {
            e1.printStackTrace( ) ;
        }

        for( int line = startline, y = starting_y; line <= endline; y += fontHeight, line++ )
        {
            g.drawString( Integer.toString( line ), 0, y ) ;
        }

    }
}

